home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1996 #15
/
Monster Media Number 15 (Monster Media)(July 1996).ISO
/
bbs_util
/
bsrc_260.zip
/
SRC.ZIP
/
SBUF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-20
|
19KB
|
820 lines
/*--------------------------------------------------------------------------*/
/* */
/* */
/* ------------ Bit-Bucket Software, Co. */
/* \ 10001101 / Writers and Distributors of */
/* \ 011110 / Freely Available<tm> Software. */
/* \ 1011 / */
/* ------ */
/* */
/* (C) Copyright 1987-96, Bit Bucket Software Co. */
/* */
/* */
/* */
/* Box Drawing subroutines for BinkleyTerm */
/* */
/* */
/* For complete details of the licensing restrictions, please refer */
/* to the License agreement, which is published in its entirety in */
/* the MAKEFILE and BT.C, and also contained in the file LICENSE.260. */
/* */
/* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */
/* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */
/* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */
/* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */
/* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */
/* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */
/* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */
/* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */
/* */
/* */
/* You can contact Bit Bucket Software Co. at any one of the following */
/* addresses: */
/* */
/* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */
/* P.O. Box 460398 AlterNet 7:42/1491 */
/* Aurora, CO 80046 BBS-Net 86:2030/1 */
/* Internet f491.n343.z1.fidonet.org */
/* */
/* Please feel free to contact us at any time to share your comments about */
/* our software and/or licensing policies. */
/* */
/* */
/* This module is derived from code developed by Augie Hansen in his */
/* book "Proficient C" published by Microsoft Press. Mr. Hansen was */
/* kind enough to give us verbal permission to use his routines, and */
/* Bob, Vince and Alan (and all our full screen users) are grateful. */
/* If you decide to use this code in some package you are doing, give */
/* some thought to going out and buying the book. He deserves that. */
/* */
/*--------------------------------------------------------------------------*/
/* Include this file before any other includes or defines! */
#include "includes.h"
#include "box.h"
#include "video.h"
BUFFER Sbuf; /* control information */
CELLP Scrnbuf; /* screen buffer array */
extern int cursor_col;
extern int cursor_row;
#define WHITEBLANK (7 << 8) | ' '
static BOXTYPE box[] =
{
'+', '+', '+', '+', '-', '-', '|', '|',
ULC11, URC11, LLC11, LRC11, HBAR1, HBAR1, VBAR1, VBAR1,
ULC22, URC22, LLC22, LRC22, HBAR2, HBAR2, VBAR2, VBAR2,
ULC12, URC12, LLC12, LRC12, HBAR1, HBAR1, VBAR2, VBAR2,
ULC21, URC21, LLC21, LRC21, HBAR2, HBAR2, VBAR1, VBAR1,
BLOCK, BLOCK, BLOCK, BLOCK, HBART, HBARB, BLOCK, BLOCK
};
void
sb_box (REGIONP win, short type, short attr)
{
register short r;
short x;
short maxr, maxc;
BOXTYPE *boxp;
boxp = &box[type];
maxc = win->c1 - win->c0;
maxr = win->r1 - win->r0;
x = maxc - 1;
/* draw top row */
sb_move (win, 0, 0);
sb_wca (win, boxp->ul, attr, 1);
sb_move (win, 0, 1);
sb_wca (win, boxp->tbar, attr, x);
sb_move (win, 0, maxc);
sb_wca (win, boxp->ur, attr, 1);
/* draw left and right sides */
for (r = 1; r < maxr; r++)
{
sb_move (win, r, 0);
sb_wca (win, boxp->lbar, attr, 1);
sb_move (win, r, maxc);
sb_wca (win, boxp->rbar, attr, 1);
}
/* draw bottom row */
sb_move (win, maxr, 0);
sb_wca (win, boxp->ll, attr, 1);
sb_move (win, maxr, 1);
sb_wca (win, boxp->bbar, attr, x);
sb_move (win, maxr, maxc);
sb_wca (win, boxp->lr, attr, 1);
}
void
sb_fill (REGIONP win, short ch, short attr)
{
register short i, j;
unsigned short ca;
ca = ((unsigned short) attr << 8) | (unsigned short) ch;
for (i = win->sr0; i <= win->sr1; i++)
{
for (j = win->sc0; j <= win->sc1; j++)
{
(Scrnbuf + i * SB_COLS + j)->cap = ca;
}
if (win->sc0 < Sbuf.lcol[i])
{
Sbuf.lcol[i] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[i])
{
Sbuf.rcol[i] = win->sc1;
}
}
Sbuf.flags |= SB_DELTA;
return;
}
void
sb_fillc (REGIONP win, short ch)
{
register short i, j;
for (i = win->sr0; i <= win->sr1; i++)
{
for (j = win->sc0; j <= win->sc1; j++)
{
(Scrnbuf + i * SB_COLS + j)->b.ch = (unsigned char) ch;
}
if (win->sc0 < Sbuf.lcol[i])
{
Sbuf.lcol[i] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[i])
{
Sbuf.rcol[i] = win->sc1;
}
}
Sbuf.flags |= SB_DELTA;
return;
}
void
sb_filla (REGIONP win, short attr)
{
register short i, j;
for (i = win->sr0; i <= win->sr1; i++)
{
for (j = win->sc0; j <= win->sc1; j++)
{
(Scrnbuf + i * SB_COLS + j)->b.attr = (unsigned char) attr;
}
if (win->sc0 < Sbuf.lcol[i])
{
Sbuf.lcol[i] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[i])
{
Sbuf.rcol[i] = win->sc1;
}
}
Sbuf.flags |= SB_DELTA;
return;
}
void
sb_init ()
{
short i, j;
CELLP c;
char q[20];
Scrnbuf = (CELLP) calloc ((unsigned short) SB_ROWS * (unsigned short) SB_COLS, sizeof (CELL));
Sbuf.bp = (CELLP) Scrnbuf;
Sbuf.row = Sbuf.col = 0;
Sbuf.lcol = (short *) calloc ((unsigned short) SB_COLS, sizeof (short));
Sbuf.rcol = (short *) calloc ((unsigned short) SB_ROWS, sizeof (short));
(void) sprintf (q, "-%d.%ds", SB_COLS - 16, SB_COLS - 16);
(void) strcpy (&stat_str[19], q);
(void) sprintf (q, "-%d.%ds", SB_COLS - 22, SB_COLS - 22);
(void) strcpy (&script_line[19], q);
if ((Scrnbuf == NULL) ||
(Sbuf.lcol == NULL) ||
(Sbuf.rcol == NULL))
{
if (Scrnbuf != NULL)
{
free (Scrnbuf);
Scrnbuf = NULL;
}
if (Sbuf.lcol != NULL)
{
free (Sbuf.lcol);
Sbuf.lcol = NULL;
}
if (Sbuf.rcol != NULL)
{
free (Sbuf.rcol);
Sbuf.rcol = NULL;
}
SB_ROWS = 23;
SB_COLS = 80;
Scrnbuf = (CELLP) calloc ((unsigned short) SB_ROWS * (unsigned short) SB_COLS, sizeof (CELL));
Sbuf.bp = (CELLP) Scrnbuf;
Sbuf.row = Sbuf.col = 0;
Sbuf.lcol = (short *) calloc ((unsigned short) SB_COLS, sizeof (short));
Sbuf.rcol = (short *) calloc ((unsigned short) SB_ROWS, sizeof (short));
(void) sprintf (q, "-%d.%ds", SB_COLS - 16, SB_COLS - 16);
(void) strcpy (&stat_str[19], q);
(void) sprintf (q, "-%d.%ds", SB_COLS - 22, SB_COLS - 22);
(void) strcpy (&script_line[19], q);
}
for (i = 0; i < (short) SB_ROWS; i++)
{
Sbuf.lcol[i] = SB_COLS;
Sbuf.rcol[i] = 0;
}
Sbuf.flags = 0;
c = Scrnbuf;
for (i = 0; i < (short) SB_ROWS; i++)
for (j = 0; j < (short) SB_COLS; j++)
{
(*c).cap = WHITEBLANK;
++c;
}
return;
}
void
sb_move (REGIONP win, register short r, register short c)
{
/* don't change anything if request is out of range */
if ((r < 0) || (r > (win->r1 - win->r0)) ||
(c < 0) || (c > (win->c1 - win->c0)))
return; /* (SB_ERR); */
win->row = r;
win->col = c;
Sbuf.row = r + win->r0;
Sbuf.col = c + win->c0;
return; /* (SB_OK); */
}
void
sb_caption (REGIONP Rgn, char *Caption)
{
sb_move (Rgn, 0, 1);
sb_puts (Rgn, Caption);
}
REGIONP
sb_new (short top, short left, short height, short width)
{
REGIONP new;
new = calloc (1, sizeof (REGION));
if (new != NULL)
{
new->r0 = new->sr0 = top;
new->r1 = new->sr1 = top + height - 1;
new->c0 = new->sc0 = left;
new->c1 = new->sc1 = left + width - 1;
new->row = new->col = 0;
new->wflags = 0;
}
return (new);
}
int
sb_popup (short top, short left, short height, short width,
int (*func) (BINK_SAVEP, int), int arg)
{
int x;
BINK_SAVEP tmp = (BINK_SAVEP) NULL;
if (fullscreen && (un_attended || doing_poll))
{
tmp = sb_save (top, left, height, width);
x = (*func) (tmp, arg);
sb_restore (tmp);
sb_show ();
}
else
{
x = (*func) (NULL, arg);
}
return (x);
}
int
sb_putc (REGIONP win, short ch)
{
short cmax, rmax;
int noscroll = 0, puterr = 0;
/* calculate the screen buffer position and limits */
cmax = win->c1 - win->c0;
rmax = win->r1 - win->r0;
Sbuf.row = win->r0 + win->row;
Sbuf.col = win->c0 + win->col;
/* process the character */
switch (ch)
{
case '\b':
/* Non destructive backspace */
if (win->col > 0)
{
--(win->col);
--(Sbuf.col);
return (SB_OK);
}
else
return (SB_ERR);
case '\r':
/* clear trailing line segment */
while (win->col < cmax)
{
if (sb_putc (win, ' ') == SB_ERR)
{
++puterr;
}
}
sb_wc (win, ' ', 1);
break;
#ifdef TABEXP
case '\t':
/* convert tabs to spaces */
lim = win->col + 8 - (win->col & 7);
while (win->col < lim)
{
if (sb_putc (win, ' ') == SB_ERR)
{
++puterr;
}
}
break;
#endif /* TABEXP */
default:
(Scrnbuf + Sbuf.row * SB_COLS + Sbuf.col)->b.ch = (unsigned char) ch;
if (Sbuf.col < Sbuf.lcol[Sbuf.row])
{
Sbuf.lcol[Sbuf.row] = Sbuf.col;
}
if (Sbuf.col > Sbuf.rcol[Sbuf.row])
{
Sbuf.rcol[Sbuf.row] = Sbuf.col;
}
break;
}
/* update the cursor position */
if (win->col < cmax)
{
++(win->col);
}
else if (win->row < rmax)
{
win->col = 0;
++(win->row);
}
else if (win->wflags & SB_SCROLL)
{
sb_scrl (win, 1);
win->col = 0;
win->row = rmax;
}
else
{
++noscroll;
}
/* update screen buffer position */
Sbuf.row = win->r0 + win->row;
Sbuf.col = win->c0 + win->col;
Sbuf.flags |= SB_DELTA;
return ((noscroll || puterr) ? SB_ERR : SB_OK);
}
void
sb_puts (REGIONP win, char *s)
{
while (*s)
{
if (sb_putc (win, *s++) == SB_ERR)
return; /* (SB_ERR); */
}
return; /* (SB_OK); */
}
unsigned char
sb_ra (REGIONP win, short r, short c)
{
return ((unsigned char) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->b.attr);
}
unsigned char
sb_rc (REGIONP win, short r, short c)
{
return ((unsigned char) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->b.ch);
}
unsigned int
sb_rca (REGIONP win, short r, short c)
{
return ((unsigned int) (Scrnbuf + (win->r0 + r) * SB_COLS + win->c0 + c)->cap);
}
int
sb_input_chars (REGIONP win, short row, short col, char *str, short len)
{
short i;
short j;
sb_move (win, row, col);
for (i = 0; i < len; i++)
(void) sb_putc (win, '_');
sb_move (win, row, col);
i = 0;
while (i < len)
{
sb_show ();
while (!KEYPRESS ())
time_release ();
j = FOSSIL_CHAR ();
if ((j & 0xff) != 0)
{
j &= 0xff;
j = toupper (j);
if (isprint (j))
{
(void) sb_putc (win, (short) (j & 0xff));
*str = (char) (j & 0xff);
++str;
++i;
++col;
continue;
}
}
switch (j)
{
case ESC:
return (1);
case BS:
case LFAR:
if (i > 0)
{
--col;
sb_move (win, row, col);
(void) sb_putc (win, '_');
sb_move (win, row, col);
--str;
--i;
}
break;
case CR:
case LV:
*str = '\0';
for (j = i; j < len; j++)
(void) sb_putc (win, ' ');
if (i)
return (0);
else
return (1);
}
}
*str = '\0';
sb_show ();
return (0);
}
BINK_SAVEP
sb_save (short top, short left, short height, short width)
{
BINK_SAVEP new;
CELLP c;
short i, j;
new = calloc (1, sizeof (BINK_SAVE));
c = new->save_cells = (CELLP) malloc (sizeof (CELL) * height * width);
new->region = sb_new (top, left, height, width);
new->save_row = (short) top;
new->save_col = (short) left;
new->save_ht = (short) height;
new->save_wid = (short) width;
j = top * SB_COLS + left;
for (i = 0; i < height; i++)
{
(void) memcpy (&c[i * width], &Scrnbuf[j], width * sizeof (CELL));
j += SB_COLS;
}
return (new);
}
void
sb_restore (BINK_SAVEP save)
{
short i, j, r;
j = save->save_row * SB_COLS + save->save_col;
for (r = save->save_row, i = 0; i < save->save_ht; r++, i++)
{
(void) memcpy (&Scrnbuf[j], &(save->save_cells[i * save->save_wid]), save->save_wid * sizeof (CELL));
j += SB_COLS;
if (save->save_col < Sbuf.lcol[r])
Sbuf.lcol[r] = save->save_col;
if (save->save_col + save->save_wid > Sbuf.rcol[r])
Sbuf.rcol[r] = save->save_col + save->save_wid;
}
Sbuf.flags |= SB_DELTA;
free ((char *) (save->save_cells));
free (save->region);
free (save);
}
void
sb_scrl (REGIONP win, short n)
{
register short r, c;
c = win->sc0;
if (n == 0)
{
/* clear the entire region to spaces */
sb_fillc (win, ' ');
}
else if (n > 0)
{
/* scroll n rows up */
for (r = win->sr0; r <= win->sr1 - n; r++)
{
(void) memcpy (Scrnbuf + r * SB_COLS + c, Scrnbuf + (r + n) * SB_COLS + c,
(unsigned short) (win->sc1 - win->sc0 + 1) * 2);
if (win->sc0 < Sbuf.lcol[r])
{
Sbuf.lcol[r] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[r])
{
Sbuf.rcol[r] = win->sc1;
}
}
for (; r <= win->sr1; r++)
{
for (c = win->sc0; c <= win->sc1; c++)
{
(Scrnbuf + r * SB_COLS + c)->b.ch = ' ';
}
if (win->sc0 < Sbuf.lcol[r])
{
Sbuf.lcol[r] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[r])
{
Sbuf.rcol[r] = win->sc1;
}
}
}
else
{
/* scroll n rows down */
n = -n;
for (r = win->sr1; r >= win->sr0 + n; r--)
{
(void) memcpy (Scrnbuf + r * SB_COLS + c, Scrnbuf + (r - n) * SB_COLS + c,
(unsigned short) (win->sc1 - win->sc0 + 1) * 2);
if (win->sc0 < Sbuf.lcol[r])
{
Sbuf.lcol[r] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[r])
{
Sbuf.rcol[r] = win->sc1;
}
}
for (; r >= win->sr0; r--)
{
for (c = win->sc0; c <= win->sc1; c++)
{
(Scrnbuf + r * SB_COLS + c)->b.ch = ' ';
}
if (win->sc0 < Sbuf.lcol[r])
{
Sbuf.lcol[r] = win->sc0;
}
if (win->sc1 > Sbuf.rcol[r])
{
Sbuf.rcol[r] = win->sc1;
}
}
}
Sbuf.flags |= SB_DELTA;
return;
}
void
sb_show ()
{
register short r;
unsigned short src_os;
char far *q;
if (screen_blank && do_screen_blank)
{
for (r = 0; r < SB_ROWS; r++)
{
q = blanks;
(void) VioWrtCellStr ((PCH) q, (USHORT) (SB_COLS * 2), (USHORT) r, (USHORT) 0, (HVIO) 0L);
}
sb_dirty ();
return;
}
/* Anything to do? */
if (!(Sbuf.flags & SB_DELTA))
{
return;
}
src_os = 0;
for (r = 0; r < SB_ROWS; r++)
{
/* Copy only changed portions of lines */
if ((Sbuf.lcol[r] < SB_COLS) && (Sbuf.rcol[r] > 0))
{
q = (char far *) (Scrnbuf + src_os + Sbuf.lcol[r]);
(void) VioWrtCellStr ((PCH) q, (USHORT) ((Sbuf.rcol[r] - Sbuf.lcol[r] + 1) * 2), (USHORT) r, (USHORT) Sbuf.lcol[r], (HVIO) 0L);
Sbuf.lcol[r] = SB_COLS;
Sbuf.rcol[r] = 0;
}
src_os += (unsigned short) SB_COLS;
}
/* the display now matches the buffer -- clear flag bit */
Sbuf.flags &= ~SB_DELTA;
/* Put sanity check on cursor_row and cursor_col here */
if (cursor_row < 0 || cursor_row > (short) (SB_ROWS - 1))
cursor_row = SB_ROWS - 1;
if (cursor_col < 0 || cursor_col > (short) (SB_COLS - 1))
cursor_col = SB_COLS - 1;
gotoxy (cursor_col, cursor_row);
return;
}
/*
* Just cleans up the structure to say it is reality - I can use this when
* I write directly to the screen for single char writes.
*/
void
sb_clean ()
{
short r;
for (r = 0; r < (short) SB_ROWS; r++)
{
Sbuf.lcol[r] = SB_COLS;
Sbuf.rcol[r] = 0;
}
Sbuf.flags &= ~SB_DELTA;
}
/*
* Make the entire buffer "dirty" so it will be updated.
*/
void
sb_dirty ()
{
short r;
for (r = 0; r < (short) SB_ROWS; r++)
{
Sbuf.lcol[r] = 0;
Sbuf.rcol[r] = SB_COLS_M_1;
}
Sbuf.flags |= SB_DELTA;
}
void
sb_wa (REGIONP win, short attr, short n)
{
short i;
short row;
short col;
i = n;
row = win->r0 + win->row;
col = win->c0 + win->col;
while (i--)
(Scrnbuf + row * SB_COLS + col + i)->b.attr = (unsigned char) attr;
/* marked the changed region */
if (col < Sbuf.lcol[row])
Sbuf.lcol[row] = col;
if (col + n > Sbuf.rcol[row])
Sbuf.rcol[row] = col + n;
Sbuf.flags |= SB_DELTA;
return; /* ((i == 0) ? SB_OK : SB_ERR); */
}
void
sb_wc (REGIONP win, short ch, short n)
{
short i;
short row;
short col;
i = n;
row = win->r0 + win->row;
col = win->c0 + win->col;
while (i--)
(Scrnbuf + row * SB_COLS + col + i)->b.ch = (unsigned char) ch;
/* marked the changed region */
if (col < Sbuf.lcol[row])
Sbuf.lcol[row] = col;
if (col + n > Sbuf.rcol[row])
Sbuf.rcol[row] = col + n;
Sbuf.flags |= SB_DELTA;
return; /* ((i == 0) ? SB_OK : SB_ERR); */
}
void
sb_wca (REGIONP win, short ch, short attr, short n)
{
short i;
short row;
short col;
unsigned short ca;
i = n;
ca = (((unsigned short) attr) << 8) | (unsigned short) ch;
row = win->r0 + win->row;
col = win->c0 + win->col;
while (i--)
(Scrnbuf + row * SB_COLS + col + i)->cap = ca;
/* marked the changed region */
if (col < Sbuf.lcol[row])
Sbuf.lcol[row] = col;
if (col + n > Sbuf.rcol[row])
Sbuf.rcol[row] = col + n;
Sbuf.flags |= SB_DELTA;
return; /* ((i == 0) ? SB_OK : SB_ERR); */
}